package com.example.wac.service.impl;

import com.auth0.jwt.exceptions.*;
import com.example.wac.constant.Constant;
import com.example.wac.entity.User;
import com.example.wac.enums.ErrorCode;
import com.example.wac.service.TokenService;
import com.example.wac.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author wuancheng
 * @description
 * @date 2022-07-08 15:45:00
 */

@Service
@Slf4j
public class TokenServiceImpl implements TokenService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public User verifyToken(String token) {
        if (StringUtils.isBlank(token)){
            throw ErrorCode.TOKEN_EMPTY_ERROR.getAppException();
        }
        String userId;
        try {
            userId = JwtUtil.getUserId(token);
        } catch (TokenExpiredException e){
            log.error("Token已过期", e);
            throw ErrorCode.TOKEN_PARSE_ERROR.getAppException();
        } catch (AlgorithmMismatchException e){
            log.error("Token算法不匹配", e);
            throw ErrorCode.TOKEN_PARSE_ERROR.getAppException();
        } catch (InvalidClaimException e){
            log.error("Token无效声明", e);
            throw ErrorCode.TOKEN_PARSE_ERROR.getAppException();
        } catch (JWTDecodeException e){
            log.error("Token解码异常", e);
            throw ErrorCode.TOKEN_PARSE_ERROR.getAppException();
        } catch (SignatureGenerationException e){
            log.error("Token签名生成异常", e);
            throw ErrorCode.TOKEN_PARSE_ERROR.getAppException();
        }
        String key = userId + ":" + token;
        User user = (User) redisTemplate.opsForValue().get(key);
        return user;
    }

    @Override
    public String generateToken(User userInfo) {
        Integer id = userInfo.getId();
        String token = JwtUtil.createJWT(String.valueOf(id));
        String key = id + ":" + token;
        redisTemplate.opsForValue().set(key, userInfo, Constant.Token.USER_LIMIT_TIME, TimeUnit.SECONDS);
        return token;
    }
}
